home *** CD-ROM | disk | FTP | other *** search
/ Hardcore Visual Basic 5.0 (2nd Edition) / Hardcore Visual Basic 5.0 - Second Edition (1997)(Microsoft Press).iso / Code / Editor.ctl < prev    next >
Text File  |  1997-06-14  |  64KB  |  1,956 lines

  1. VERSION 5.00
  2. Object = "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.1#0"; "richtx32.ocx"
  3. Begin VB.UserControl XEditor 
  4.    Alignable       =   -1  'True
  5.    ClientHeight    =   1836
  6.    ClientLeft      =   0
  7.    ClientTop       =   0
  8.    ClientWidth     =   2196
  9.    PaletteMode     =   4  'None
  10.    ScaleHeight     =   1836
  11.    ScaleWidth      =   2196
  12.    ToolboxBitmap   =   "Editor.ctx":0000
  13.    Begin RichTextLib.RichTextBox txt 
  14.       Height          =   1728
  15.       Left            =   -36
  16.       TabIndex        =   0
  17.       Top             =   -84
  18.       Width           =   2028
  19.       _ExtentX        =   3577
  20.       _ExtentY        =   3048
  21.       _Version        =   327680
  22.       BorderStyle     =   0
  23.       Enabled         =   -1  'True
  24.       HideSelection   =   0   'False
  25.       ScrollBars      =   3
  26.       AutoVerbMenu    =   -1  'True
  27.       TextRTF         =   $"Editor.ctx":00FA
  28.       BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
  29.          Name            =   "Arial"
  30.          Size            =   7.8
  31.          Charset         =   0
  32.          Weight          =   400
  33.          Underline       =   0   'False
  34.          Italic          =   0   'False
  35.          Strikethrough   =   0   'False
  36.       EndProperty
  37.    End
  38. End
  39. Attribute VB_Name = "XEditor"
  40. Attribute VB_GlobalNameSpace = False
  41. Attribute VB_Creatable = True
  42. Attribute VB_PredeclaredId = False
  43. Attribute VB_Exposed = True
  44. Attribute VB_Ext_KEY = "RepId" ,"4FB51841-CEAF-11CF-A15E-00AA00A74D48-005c"
  45. Option Explicit
  46.  
  47. Public Enum EErrorEditor
  48.     eeBaseEditor = 13720    ' XEditor
  49. End Enum
  50.  
  51. Public Enum ELoadSave
  52.     elsDefault = -1
  53.     elsrtf
  54.     elstext
  55. End Enum
  56.  
  57. Public Enum EWordWrap
  58.     NoWordWrap = 65535
  59. End Enum
  60.  
  61. Public Enum ESearchEvent
  62.     eseFindWhat
  63.     eseReplaceWith
  64.     eseCase
  65.     eseWholeWord
  66.     eseDirection
  67. End Enum
  68.  
  69. Public Enum ESearchDir
  70.     esdAll
  71.     esdDown
  72.     esdUp
  73. End Enum
  74. Private esdDir As ESearchDir
  75.  
  76. ' Private variables for properties
  77. Private cCharPerTab As Integer
  78. Private sFilter As String, iFilter As Integer
  79. Private sFilePath As String
  80. Private fTextMode As Boolean
  81. Private fSaveWordWrap As Boolean
  82. Private fEnableTab As Boolean
  83. Private ordAppearance As AppearanceConstants
  84. Private ordScrollBars As ScrollBarsConstants
  85. Private fSearchOptionCase As Boolean
  86. Private fSearchOptionWord As Boolean  ' Left as an exercise
  87. Private cSearchActive As Integer
  88. Private fOverWrite As Boolean
  89. Private nFilters As New Collection
  90. Private xMin As Single, yMin As Single
  91. Private clrFore As OLE_COLOR
  92. Private vecTab As New CVectorBool
  93. Private cFindWhatMax As Long
  94. Private cReplaceWithMax As Long
  95. Private nFindWhat As New Collection
  96. Private nReplaceWith As New Collection
  97. Private fontDefault As Font
  98. ' Dialogs at module level so they can be destroyed
  99. Private finddlg As New FSearch
  100.  
  101. 'Event Declarations
  102.  
  103. ' RichTextBox events
  104. Event Click()
  105. Attribute Click.VB_Description = "Occurs when the user presses and then releases a mouse button over an object."
  106. Event DblClick()
  107. Attribute DblClick.VB_Description = "Occurs when the user presses and releases a mouse button and then presses and releases it again over an object."
  108. Event KeyDown(KeyCode As Integer, Shift As Integer)
  109. Attribute KeyDown.VB_Description = "Occurs when the user presses a key while an object has the focus."
  110. Event KeyPress(KeyAscii As Integer)
  111. Attribute KeyPress.VB_Description = "Occurs when the user presses and releases an ANSI key."
  112. Event KeyUp(KeyCode As Integer, Shift As Integer)
  113. Attribute KeyUp.VB_Description = "Occurs when the user releases a key while an object has the focus."
  114. Event MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  115. Attribute MouseDown.VB_Description = "Occurs when the user presses a mouse button."
  116. Event MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  117. Attribute MouseMove.VB_Description = "Occurs when the user moves the mouse."
  118. Event MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
  119. Attribute MouseUp.VB_Description = "Occurs when the user presses and releases a mouse button."
  120. Event Change()
  121. Attribute Change.VB_Description = "Indicates that the contents of a control have changed."
  122. Event OLECompleteDrag(Effect As Long)
  123. Attribute OLECompleteDrag.VB_Description = "OLECompleteDrag event"
  124. Event OLEDragDrop(Data As DataObject, Effect As Long, _
  125.                   Button As Integer, Shift As Integer, _
  126.                   X As Single, Y As Single)
  127. Event OLEDragOver(Data As DataObject, Effect As Long, _
  128.                   Button As Integer, Shift As Integer, _
  129.                   X As Single, Y As Single, State As Integer)
  130. Event OLEGiveFeedback(Effect As Long, DefaultCursors As Boolean)
  131. Event OLESetData(Data As DataObject, DataFormat As Integer)
  132. Attribute OLESetData.VB_Description = "OLESetData event"
  133. Event OLEStartDrag(Data As DataObject, AllowedEffects As Long)
  134. Attribute OLEStartDrag.VB_Description = "OLEStartDrag event"
  135. Event SearchChange(Kind As ESearchEvent)
  136. Event SelChange()
  137.  
  138. ' New event that reports status
  139. Event StatusChange(LineCur As Long, LineCount As Long, _
  140.                    ColumnCur As Long, ColumnCount As Long, _
  141.                    CharacterCur As Long, CharacterCount As Long, _
  142.                    DirtyBit As Boolean)
  143.  
  144.  
  145. Private Sub UserControl_AmbientChanged(PropertyName As String)
  146.      BugLocalMessage "XEditor UserControl_AmbientChanged: " & PropertyName
  147. End Sub
  148.  
  149. Private Sub UserControl_EnterFocus()
  150.     BugLocalMessage "XEditor UserControl_EnterFocus"
  151. End Sub
  152.  
  153. Private Sub UserControl_ExitFocus()
  154.     BugLocalMessage "XEditor UserControl_ExitFocus"
  155. End Sub
  156.  
  157. Private Sub UserControl_Initialize()
  158.     BugLocalMessage "XEditor UserControl_Initialize"
  159.     xMin = Width / 2
  160.     yMin = Height / 2
  161.     SearchOptionDirection = esdAll
  162. End Sub
  163.  
  164. Private Sub UserControl_GotFocus()
  165.     BugLocalMessage "XEditor UserControl_GotFocus"
  166. End Sub
  167.  
  168. Private Sub UserControl_LostFocus()
  169.     BugLocalMessage "XEditor UserControl_LostFocus"
  170. End Sub
  171.  
  172. Private Sub txt_GotFocus()
  173.     BugLocalMessage "XEditor txt_GotFocus"
  174.     If fEnableTab And Ambient.UserMode Then
  175.         ' Ignore errors for controls without the TabStop property
  176.         On Error Resume Next
  177.         Dim i As Long, vControl As Variant, f As Boolean
  178.         ' Clear tab vector
  179.         i = 1
  180.         Set vecTab = Nothing
  181.         ' Stop changing focus when pressing TAB
  182.         For Each vControl In Parent.Controls
  183.             f = vControl.TabStop
  184.             vecTab(i) = f
  185.             vControl.TabStop = False
  186.             i = i + 1
  187.         Next
  188.     End If
  189. End Sub
  190.  
  191. Private Sub txt_LostFocus()
  192.     BugLocalMessage "XEditor txt_LostFocus"
  193.     If fEnableTab And Ambient.UserMode Then
  194.         ' Ignore errors for controls without the TabStop property
  195.         On Error Resume Next
  196.         Dim i As Long, vControl As Variant
  197.         ' Restore TabStops from vector
  198.         i = 1
  199.         For Each vControl In Parent.Controls
  200.             vControl.TabStop = vecTab(i)
  201.             i = i + 1
  202.         Next
  203.     End If
  204. End Sub
  205.  
  206. Private Sub UserControl_Terminate()
  207.     BugLocalMessage "XEditor UserControl_Terminate"
  208.     ' If a find or replace dialog is active, terminate it
  209.     Set finddlg = Nothing
  210. End Sub
  211.  
  212. 'Initialize Properties for User Control
  213. Private Sub UserControl_InitProperties()
  214.     BugLocalMessage "XEditor UserControl_InitProperties"
  215.     fTextMode = True
  216.     ordAppearance = rtfThreeD
  217. '    ordScrollBars = rtfBoth
  218. #If afDebug Then
  219.     ChDrive App.Path
  220.     ChDir App.Path
  221. #End If
  222.     cCharPerTab = 8
  223.     nFilters.Add "Text files (*.txt): *.txt"
  224.     nFilters.Add "Rich text files (*.rtf): *.rtf"
  225.     nFilters.Add "All files (*.*): *.*"
  226.     Text = sEmpty
  227.     Extender.Name = UniqueControlName("edit", Extender)
  228.     UserControl_Load
  229. End Sub
  230.  
  231. 'Load property values from storage
  232. Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
  233. With txt
  234.     BugLocalMessage "XEditor UserControl_ReadProperties"
  235.     ordAppearance = PropBag.ReadProperty("Appearance", rtfThreeD)
  236.     .AutoVerbMenu = PropBag.ReadProperty("AutoVerbMenu", .AutoVerbMenu)
  237.     .BackColor = PropBag.ReadProperty("BackColor", vbWindowBackground)
  238.     .BorderStyle = PropBag.ReadProperty("BorderStyle", rtfFixedSingle)
  239.     .BulletIndent = PropBag.ReadProperty("BulletIndent", 0)
  240.     ' Enabled provided by extender
  241.     sFilePath = PropBag.ReadProperty("FileName", sEmpty)
  242.     Dim s As String, sT As String
  243.     s = PropBag.ReadProperty("FileOpenFilter", sEmpty)
  244.     Set .Font = PropBag.ReadProperty("Font", Ambient.Font)
  245.     TextColor = PropBag.ReadProperty("TextColor", vbWindowText)
  246.     ' Height in extender
  247.     ' HelpContextID on extender
  248.     .HideSelection = PropBag.ReadProperty("HideSelection", False)
  249.     ' hWnd run time only
  250.     ' Index on extender
  251.     ' Left in Extender
  252.     ' Line, Lines run time only
  253.     ' LinePosition, LineLength run time only
  254.     ' LineText run time only
  255.     .Locked = PropBag.ReadProperty("Locked", False)
  256.     Set .MouseIcon = PropBag.ReadProperty("MouseIcon", Nothing)
  257.     .MousePointer = PropBag.ReadProperty("MousePointer", rtfDefault)
  258.     .OLEDragMode = PropBag.ReadProperty("OLEDragMode", rtfOLEDragAutomatic)
  259.     .OLEDropMode = PropBag.ReadProperty("OLEDropMode", rtfOLEDropAutomatic)
  260.     fOverWrite = PropBag.ReadProperty("OverWrite", False)
  261.     ' Percent run time only
  262.     .RightMargin = PropBag.ReadProperty("RightMargin", 0)
  263.     ordScrollBars = PropBag.ReadProperty("ScrollBars", rtfBoth)
  264.     ScrollBars = ordScrollBars
  265.     ' SearchOptionDirection, SearchOptionCase, SearchOptionWord run time only
  266.     ' SelAlignment run time only
  267.     ' SelBold run time only
  268.     ' SelBullet run time only
  269.     ' SelCharOffset run time only
  270.     ' SelColor run time only
  271.     ' SelFontName run time only
  272.     ' SelFontSize run time only
  273.     ' SelHangingIndent run time only
  274.     ' SelIndent run time only
  275.     ' SelItalic run time only
  276.     ' SelLength run time only
  277.     ' SelProtected run time only
  278.     ' SelRightIndent run time only
  279.     ' SelRTF run time only
  280.     ' SelStart run time only
  281.     ' SelStrikeThru run time only
  282.     ' SelTabCount run time only
  283.     ' .SelTabs(sElement) = PropBag.ReadProperty("SelTabs" & Index, 0)
  284.     ' SelTabs run time only
  285.     ' SelText run time only
  286.     ' SelUnderline run time only
  287.     .Text = PropBag.ReadProperty("Text", sEmpty)
  288.     ' TextRTF run time only
  289.     TextMode = PropBag.ReadProperty("TextMode", True)
  290.     UserControl_Load
  291. End With
  292. End Sub
  293.  
  294. 'Write property values to storage
  295. Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
  296.     BugLocalMessage "XEditor UserControl_WriteProperties"
  297. With txt
  298.     PropBag.WriteProperty "Appearance", ordAppearance, rtfThreeD
  299.     PropBag.WriteProperty "AutoVerbMenu", .AutoVerbMenu, False
  300.     PropBag.WriteProperty "BackColor", .BackColor, vbWindowBackground
  301.     PropBag.WriteProperty "BorderStyle", .BorderStyle, rtfFixedSingle
  302.     PropBag.WriteProperty "BulletIndent", .BulletIndent, 0
  303.     ' Character, Characters run time only
  304.     ' Column, Columns run time only
  305.     ' Container controlled by extender
  306.     ' DirtyBit run time only
  307.     ' Enabled handled by extender
  308.     PropBag.WriteProperty "FileName", sFilePath, sEmpty
  309.     Dim s As String, v As Variant
  310.     'For Each v In nFilters
  311.     '    s = s & v & sCrLf
  312.     'Next
  313.     's = Left$(s, Len(s) - 2)
  314.     PropBag.WriteProperty "FileOpenFilter", s, sEmpty
  315.     ' FindWhat, ReplaceWith run time only
  316.     ' FindWhatList, ReplaceWithList run time only
  317.     PropBag.WriteProperty "Font", .Font, Ambient.Font
  318.     PropBag.WriteProperty "TextColor", TextColor, vbWindowText
  319.     ' Height in extender
  320.     ' hWnd run time only
  321.     PropBag.WriteProperty "HideSelection", .HideSelection, False
  322.     PropBag.WriteProperty "Locked", .Locked, False
  323.     PropBag.WriteProperty "MouseIcon", .MouseIcon, Nothing
  324.     PropBag.WriteProperty "MousePointer", .MousePointer, rtfDefault
  325.     PropBag.WriteProperty "OLEDragMode", .OLEDragMode, rtfOLEDragAutomatic
  326.     PropBag.WriteProperty "OLEDropMode", .OLEDropMode, rtfOLEDropAutomatic
  327.     PropBag.WriteProperty "OverWrite", fOverWrite, False
  328.     PropBag.WriteProperty "RightMargin", .RightMargin, 0
  329.     PropBag.WriteProperty "ScrollBars", ordScrollBars, rtfBoth
  330.     ' SelAlignment run time only
  331.     ' SelBold run time only
  332.     ' SelBullet run time only
  333.     ' SelCharOffset run time only
  334.     ' SelColor run time only
  335.     ' SelFontName run time only
  336.     ' SelFontSize run time only
  337.     ' SelHangingIndent run time only
  338.     ' SelIndent run time only
  339.     ' SelItalic run time only
  340.     ' SelLength run time only
  341.     ' SelProtected run time only
  342.     ' SelRightIndent run time only
  343.     ' SelRTF run time only
  344.     ' SelStart run time only
  345.     ' SelStrikeThru run time only
  346.     ' SelTabCount run time only
  347.     ' SelTabs" & Index, .SelTabs(sElement), 0
  348.     ' SelText run time only
  349.     ' SelUnderline run time only
  350.     PropBag.WriteProperty "Text", .Text, sEmpty
  351.     PropBag.WriteProperty "TextMode", TextMode, True
  352. End With
  353. End Sub
  354.  
  355. Private Sub UserControl_Resize()
  356.     BugLocalMessage "XEditor UserControl_Resize"
  357.     If Width < xMin Then Width = xMin
  358.     If Height < yMin Then Height = yMin
  359.     ' Adjust internal RichTextBox to be the size of the UserControl
  360.     txt.Move 0, 0, UserControl.ScaleWidth, UserControl.ScaleHeight
  361. End Sub
  362.  
  363. Private Sub UserControl_Load()
  364.     DirtyBit = False
  365.     InitFilters
  366.     If fOverWrite Then
  367.         ' Make overwrite state match fOverWrite variable
  368.         SendMessage txt.hWnd, WM_KEYDOWN, ByVal VK_INSERT, ByVal &H510001
  369.         SendMessage txt.hWnd, WM_KEYUP, ByVal VK_INSERT, ByVal &HC0510001
  370.     End If
  371.     Set fontDefault = Font
  372. End Sub
  373.  
  374. '' New methods
  375.  
  376. Sub FileNew()
  377.     Text = sEmpty
  378.     sFilePath = sEmpty
  379.     DirtyBit = False
  380. End Sub
  381.  
  382. Function FileOpen() As Boolean
  383.     Dim f As Boolean, sFile As String, fReadOnly As Boolean
  384.     f = VBGetOpenFileName( _
  385.             FileName:=sFile, _
  386.             ReadOnly:=fReadOnly, _
  387.             Filter:=FilterString, _
  388.             Owner:=hWnd)
  389.     If f And sFile <> sEmpty Then
  390.         TextMode = Not IsRTF(sFile)
  391.         LoadFile sFile
  392.         If fReadOnly Then Locked = True
  393.         FileOpen = True
  394.     End If
  395. End Function
  396.  
  397. Property Get FileOpenFilter(Optional ByVal i As Integer) As String
  398.     If i = 0 Then i = 1
  399.     If i > nFilters.Count Or i < 1 Then Exit Property
  400.     FileOpenFilter = nFilters(i)
  401. End Property
  402.  
  403. Property Let FileOpenFilter(Optional ByVal i As Integer, _
  404.                             sFilterA As String)
  405.     If i > nFilters.Count Or i < 1 Then
  406.         nFilters.Add sFilterA
  407.     Else
  408.         nFilters.Add sFilterA, , i
  409.     End If
  410.     PropertyChanged "FileOpenFilter"
  411. End Property
  412.  
  413. Sub FileSave()
  414.     If FileName = sEmpty Then
  415.         FileSaveAs
  416.     Else
  417.         SaveFile FileName
  418.     End If
  419.     DirtyBit = False
  420. End Sub
  421.  
  422. Function FileSaveAs() As Boolean
  423.     Dim f As Boolean, sFile As String
  424.     ' Default includes OverWritePrompt so you can confirm
  425.     f = VBGetSaveFileName( _
  426.             FileName:=sFile, _
  427.             Filter:=FilterString, _
  428.             Owner:=hWnd)
  429.     If f And sFile <> sEmpty Then
  430.         ' Be sure you're right, then go ahead
  431.         If ExistFile(sFile) Then Kill sFile
  432.         SaveFile sFile
  433.         FileSaveAs = True
  434.     End If
  435. End Function
  436.  
  437. Sub FilePrint()
  438.     Dim hDC As Long, epr As EPrintRange
  439.     If VBPrintDlg(hDC, DisablePageNumbers:=True, _
  440.                        DisableSelection:=SelLength = 0, _
  441.                        PrintRange:=epr, _
  442.                        ShowPrintToFile:=False, _
  443.                        Owner:=hWnd) Then
  444.         ' We don't handle request to print specific pages
  445.         If epr = eprAll Then
  446.             ' Print all regardless of selection
  447.             SelPrint hDC, True
  448.         Else
  449.             SelPrint hDC
  450.         End If
  451.     End If
  452. End Sub
  453.  
  454. Sub FilePageSetup()
  455.     If VBPageSetupDlg(Owner:=hWnd) Then
  456.         
  457.     End If
  458. End Sub
  459.  
  460. #If 1 Then
  461. Function OptionColor(Optional ByVal clr As Long = vbBlack) As Long
  462.     ' Make sure it's an RGB color
  463.     clr = TranslateColor(clr)
  464.     ' Choose a solid color
  465.     Call VBChooseColor(Color:=clr, AnyColor:=False, Owner:=hWnd)
  466.     ' Return color, whether successful or not
  467.     OptionColor = clr
  468. End Function
  469. #ElseIf 0 Then
  470. Function OptionColor(Optional ByVal clr As Long = vbBlack) As Long
  471. Dim choose As New ChooseColor
  472. With choose
  473.     ' Make sure it's an RGB color
  474.     .Color = TranslateColor(clr)
  475.     .hWnd = hWnd
  476.     ' No property to specify solid colors
  477.     ' Return color, whether successful or not
  478.     If .Show Then
  479.         OptionColor = choose.Color
  480.     Else
  481.         OptionColor = clr
  482.     End If
  483. End With
  484. End Function
  485. #ElseIf 0 Then
  486. Function OptionColor(Optional ByVal clr As Long = vbBlack) As Long
  487. With dlgColor
  488.     ' No VB constant for CC_SOLIDCOLOR, but it works
  489.     .flags = cdlCCRGBInit Or CC_SolidColor
  490.     ' Make sure it's an RGB color
  491.     .Color = TranslateColor(clr)
  492.     .hWnd = hWnd
  493.     ' Can only recognize cancel with error trapping
  494.     .CancelError = True
  495.     On Error Resume Next
  496.     .ShowColor
  497.     ' Return color, whether successful or not
  498.     If Err Then
  499.         OptionColor = clr
  500.     Else
  501.         OptionColor = .Color
  502.     End If
  503. End With
  504. End Function
  505. #End If
  506.  
  507. Sub OptionFont(Optional fSelection As Boolean)
  508.     Dim f As Boolean, fnt As StdFont, clr As Long
  509.     If fSelection Then
  510.         Set fnt = New StdFont
  511.         If IsNull(SelBold) Then fnt.Bold = fontDefault.Bold Else fnt.Bold = SelBold
  512.         If IsNull(SelColor) Then clr = 0 Else clr = SelColor
  513.         If IsNull(SelFontName) Then fnt.Name = fontDefault.Name Else fnt.Name = SelFontName
  514.         If IsNull(SelFontSize) Then fnt.Size = fontDefault.Size Else fnt.Size = SelFontSize
  515.         If IsNull(SelItalic) Then fnt.Italic = fontDefault.Italic Else fnt.Italic = SelItalic
  516.         If IsNull(SelStrikeThru) Then fnt.Strikethrough = fontDefault.Strikethrough Else fnt.Strikethrough = SelStrikeThru
  517.         If IsNull(SelUnderline) Then fnt.Underline = fontDefault.Underline Else fnt.Underline = SelUnderline
  518.     Else
  519.         Set fnt = Font
  520.         clr = TextColor
  521.     End If
  522.     f = VBChooseFont(CurFont:=fnt, _
  523.                      Color:=clr, _
  524.                      flags:=CF_EFFECTS Or CF_BOTH)
  525.     If Not f Then Exit Sub
  526.     If fSelection Then
  527.         SelColor = clr
  528.         SelBold = fnt.Bold
  529.         SelFontName = fnt.Name
  530.         SelFontSize = fnt.Size
  531.         SelItalic = fnt.Italic
  532.         SelStrikeThru = fnt.Strikethrough
  533.         SelUnderline = fnt.Underline
  534.     Else
  535.         Set Font = fnt
  536.         TextColor = clr
  537.     End If
  538.     Refresh
  539. End Sub
  540.  
  541. Public Function DirtyDialog() As Boolean
  542.     Dim s As String
  543.     DirtyDialog = True ' Assume success
  544.     ' Done if no dirty file to save
  545.     If Not DirtyBit Then Exit Function
  546.     ' Prompt for action if dirty file
  547.     s = "File not saved: " & FileName & sCrLf & "Save now?"
  548.     Select Case MsgBox(s, vbYesNoCancel)
  549.     Case vbYes
  550.         ' Save old file
  551.         FileSave
  552.     Case vbCancel
  553.         ' User wants to terminate file change
  554.         DirtyDialog = False
  555.     Case vbNo
  556.         ' Do nothing if user wants to throw away changes
  557.     End Select
  558. End Function
  559.  
  560. ' Cut, copy, paste methods
  561. Sub EditCopy()
  562.     Clipboard.SetText txt.SelText
  563. End Sub
  564.  
  565. Sub EditCut()
  566.     Clipboard.SetText txt.SelText
  567.     txt.SelText = sEmpty
  568. End Sub
  569.  
  570. Sub EditDelete()
  571.     If txt.SelLength = 0 Then txt.SelLength = 1
  572.     txt.SelText = sEmpty
  573. End Sub
  574.  
  575. Sub EditPaste()
  576.     txt.SelText = Clipboard.GetText()
  577. End Sub
  578.  
  579. Sub EditSelectAll()
  580.     txt.SelStart = 0
  581.     txt.SelLength = Me.Characters
  582. End Sub
  583.  
  584. Sub EditUndo()
  585.     Call SendMessage(txt.hWnd, EM_UNDO, ByVal 0&, ByVal 0&)
  586. End Sub
  587.  
  588. Sub ClearUndo()
  589.     Call SendMessage(txt.hWnd, EM_EMPTYUNDOBUFFER, ByVal 0&, ByVal 0&)
  590. End Sub
  591.  
  592. Sub Scroll(Optional iLine As Long = 1, Optional iCol As Long = 0)
  593.     SendMessage txt.hWnd, EM_LINESCROLL, ByVal iCol, ByVal iLine
  594. End Sub
  595.  
  596. Sub ScrollToCaret()
  597.     SendMessage txt.hWnd, EM_SCROLLCARET, ByVal 0&, ByVal 0&
  598. End Sub
  599.  
  600. Sub PageUp()
  601.     SendMessage txt.hWnd, WM_VSCROLL, ByVal SB_PAGEUP, ByVal 0&
  602. End Sub
  603.  
  604. Sub PageDown()
  605.     SendMessage txt.hWnd, WM_VSCROLL, ByVal SB_PAGEDOWN, ByVal 0&
  606. End Sub
  607.  
  608. ' Search and Replace functions
  609.  
  610. Sub SearchFind()
  611.     ' Set properties on form
  612.     Set finddlg.Editor = Me
  613.     finddlg.ReplaceMode = False
  614.     ' Load, but don't show yet
  615.     Load finddlg
  616. End Sub
  617.  
  618. Sub SearchFindNext()
  619.     If FindWhat = sEmpty Then
  620.         SearchFind
  621.     Else
  622.         Call FindNext(FindWhat)
  623.     End If
  624. End Sub
  625.  
  626. Sub SearchReplace()
  627.     ' Set properties on form
  628.     Set finddlg.Editor = Me
  629.     finddlg.ReplaceMode = True
  630.     ' Load, but don't show yet
  631.     Load finddlg
  632. End Sub
  633.  
  634. Function FindNext(Optional What As String, _
  635.                   Optional MarkText As Boolean = True) As Integer
  636. With txt
  637.     Dim fWrap As Boolean, eso As ESearchOptions
  638.     
  639.     ' Set up options
  640.     fWrap = (SearchOptionDirection = esdAll)
  641.     If SearchOptionDirection = esdUp Then eso = esoBackward
  642.     If SearchOptionCase Then eso = eso Or esoCaseSense
  643.     If SearchOptionWord Then eso = eso Or esoWholeWord
  644.     If What = sNullStr Then What = FindWhat
  645.     
  646.     ' Search for string
  647.     Dim iPos As Integer
  648.     If eso And esoBackward Then
  649.         iPos = .SelStart
  650.     Else
  651.         iPos = .SelStart + .SelLength
  652.     End If
  653. '    If (eso And esoBackward) = 0 Then iPos = iPos + 2
  654.     iPos = FindString(.Text, What, iPos, eso)
  655.  
  656.     ' If not found, wrap if appropriate
  657.     If iPos = 0 Then
  658.         If fWrap Then
  659.             iPos = IIf(eso And esoBackward, Len(.Text), 1)
  660.             iPos = FindString(.Text, What, iPos, eso)
  661.         End If
  662.     End If
  663.     
  664.     ' Mark found text if requested
  665.     If MarkText And iPos Then
  666.         .SelStart = iPos - 1
  667.         .SelLength = Len(What)
  668.     End If
  669.     FindNext = iPos
  670. End With
  671. End Function
  672.  
  673. Function ReplaceNext(Optional Find As String, _
  674.                      Optional Replace As String) As Integer
  675.         
  676.     If Find = sNullStr Then Find = FindWhat
  677.     If Find = sEmpty Then Exit Function
  678.     
  679.     ' If first match not yet found, find it
  680.     Dim i As Integer, s As String
  681.     s = Mid(txt.Text, txt.SelStart + 1, Len(Find))
  682.     If StrComp(s, Find, -SearchOptionCase) Then
  683.         i = FindNext(Find)
  684.         If i = 0 Then Exit Function
  685.     Else ' If already found, make sure it's marked
  686.         i = txt.SelStart + 1
  687.         txt.SelLength = Len(Find)
  688.     End If
  689.  
  690.     ' Replace text
  691.     If i Then
  692.         txt.SelText = Replace
  693.         ReplaceNext = i
  694.     End If
  695.  
  696. End Function
  697.  
  698. '' New properties
  699. Property Get CanUndo() As Boolean
  700.     CanUndo = SendMessage(txt.hWnd, EM_CANUNDO, ByVal 0&, ByVal 0&)
  701. End Property
  702.  
  703. Property Get CanPaste() As Boolean
  704.     If TextMode Then
  705.         CanPaste = SendMessage(txt.hWnd, EM_CANPASTE, ByVal 0&, ByVal 0&)
  706.     Else
  707.         CanPaste = SendMessage(txt.hWnd, EM_CANPASTE, ByVal CF_TEXT, ByVal 0&)
  708.     End If
  709. End Property
  710.  
  711. Property Get TextMode() As Boolean
  712.     TextMode = fTextMode
  713. End Property
  714.  
  715. Property Let TextMode(ByVal fTextModeA As Boolean)
  716.     ' Change to TextMode dirties the file, but not vice versa
  717.     If Not fTextMode And fTextMode <> fTextModeA Then DirtyBit = True
  718.     fTextMode = fTextModeA
  719.     PropertyChanged "TextMode"
  720. End Property
  721.  
  722. ' Optional argument character in which line is located
  723. Property Get Line(Optional ByVal iChar As Long = -1) As Long
  724. Attribute Line.VB_MemberFlags = "400"
  725.     If iChar = -1 Then iChar = txt.SelStart
  726.     ' Current line (zero adjusted)
  727.     Line = 1 + GetLineFromChar(iChar)
  728. End Property
  729.  
  730. Property Let Line(Optional ByVal iChar As Long = -1, ByVal iLineA As Long)
  731.     ' Don't use optional parameter on Let
  732.     BugAssert iChar = -1
  733.     txt.SelStart = LinePosition(iLineA - 1) - 1
  734. End Property
  735.  
  736. Property Get Lines() As Long
  737. Attribute Lines.VB_MemberFlags = "400"
  738.     ' Count of lines
  739.     Lines = SendMessage(txt.hWnd, EM_GETLINECOUNT, ByVal 0&, ByVal 0&)
  740. End Property
  741.  
  742. Property Get Character() As Long
  743. Attribute Character.VB_MemberFlags = "400"
  744.     ' Current character
  745.     Character = txt.SelStart + 1
  746. End Property
  747.  
  748. Property Let Character(ByVal iPos As Long)
  749.     txt.SelStart = iPos - 1
  750. End Property
  751.  
  752. Property Get Characters() As Long
  753. Attribute Characters.VB_MemberFlags = "400"
  754.     Dim i As Long
  755.     ' Length is position of last line plus length of last line
  756.     i = SendMessage(txt.hWnd, EM_LINEINDEX, ByVal Lines - 1, ByVal 0&)
  757.     Characters = i + SendMessage(txt.hWnd, EM_LINELENGTH, _
  758.                                  ByVal Lines - 1, ByVal 0&)
  759. End Property
  760.  
  761. ' Optional argument character in which column is located
  762. Property Get Column(Optional ByVal iChar As Long = -1) As Long
  763. Attribute Column.VB_MemberFlags = "400"
  764.     If iChar = -1 Then iChar = txt.SelStart
  765.     ' Column is current position minus position of line start
  766.     Dim i As Long
  767.     i = SendMessage(txt.hWnd, EM_LINEINDEX, _
  768.                     ByVal Line(iChar) - 1, ByVal 0&)
  769.     Column = Character - i
  770. End Property
  771.  
  772. Property Let Column(Optional ByVal iChar As Long = -1, ByVal iColA As Long)
  773.     ' Don't use optional parameter on Let
  774.     BugAssert iChar = -1
  775.     txt.SelStart = LinePosition + iColA - 2
  776. End Property
  777.  
  778. Property Get Columns() As Long
  779. Attribute Columns.VB_MemberFlags = "400"
  780.     ' Column count is current line length
  781.     Columns = SendMessage(txt.hWnd, EM_LINELENGTH, _
  782.                           ByVal Character - 1, ByVal 0&)
  783. End Property
  784.  
  785. Property Get Percent() As Integer
  786. Attribute Percent.VB_MemberFlags = "400"
  787.     Percent = (Character / (Characters + 1)) * 100
  788. End Property
  789.  
  790. Property Let Percent(ByVal iA As Integer)
  791.     txt.SelStart = Characters * (iA / 100)
  792. End Property
  793.  
  794. Property Get LinePosition(Optional ByVal iLine As Long = -1) As Long
  795. Attribute LinePosition.VB_MemberFlags = "400"
  796.     LinePosition = SendMessage(txt.hWnd, EM_LINEINDEX, _
  797.                                ByVal iLine, ByVal 0&) + 1
  798. End Property
  799.  
  800. Property Get LineLength(Optional iLine As Long = -1) As Long
  801. Attribute LineLength.VB_MemberFlags = "400"
  802.     If iLine = -1 Then iLine = Line
  803.     LineLength = SendMessage(txt.hWnd, EM_LINELENGTH, _
  804.                              ByVal LinePosition(iLine), ByVal 0&)
  805. End Property
  806.  
  807. Property Get FirstVisibleLine() As Long
  808.     Line = 1 + SendMessage(txt.hWnd, EM_GETFIRSTVISIBLELINE, _
  809.                            ByVal 0&, ByVal 0&)
  810. End Property
  811.  
  812. Property Get LineText(Optional iLine As Long = -1) As String
  813. Attribute LineText.VB_MemberFlags = "400"
  814.     If iLine = -1 Then iLine = Line
  815.     Const cCharMax = 252
  816.     Dim s As String, c As Integer
  817.     s = Space$(cCharMax + 3)
  818.     Mid$(s, 1, 1) = Chr$(cCharMax And &HFF)
  819.     Mid$(s, 2, 1) = Chr$(cCharMax \ 256)
  820.     c = SendMessageStr(txt.hWnd, EM_GETLINE, iLine - 1, s)
  821.     LineText = Left$(s, c)
  822. End Property
  823.  
  824. Function GetLineFromChar(iPos As Long) As Long
  825. Attribute GetLineFromChar.VB_Description = "Returns the number of the line containing a specified character position."
  826.     GetLineFromChar = txt.GetLineFromChar(iPos)
  827. End Function
  828.  
  829. Property Get Tabs() As Integer
  830. Attribute Tabs.VB_MemberFlags = "400"
  831.     Tabs = cCharPerTab
  832. End Property
  833.  
  834. Property Let Tabs(ByVal cTab As Integer)
  835.     Dim c As Long
  836.     c = cTab * 4 ' Assume 4 dialog box units per character
  837.     c = SendMessage(txt.hWnd, EM_SETTABSTOPS, ByVal 1&, c)
  838.     cCharPerTab = cTab
  839.     PropertyChanged "Tabs"
  840. End Property
  841.  
  842. Property Get EnableTab() As Boolean
  843.     EnableTab = fEnableTab
  844. End Property
  845.  
  846. Property Let EnableTab(ByVal fEnableTabA As Boolean)
  847.     fEnableTab = fEnableTabA
  848.     PropertyChanged "EnableTab"
  849. End Property
  850.  
  851.  
  852. Sub SelVisible(fVisible As Boolean)
  853.     SendMessage txt.hWnd, EM_HIDESELECTION, ByVal -fVisible, ByVal 0&
  854. End Sub
  855.  
  856. ' Find and Replace option properties
  857. Property Get FindWhat(Optional iIndex As Long = 1) As String
  858. Attribute FindWhat.VB_MemberFlags = "400"
  859. With nFindWhat
  860.     If .Count = 0 Or iIndex > .Count Then Exit Property
  861.     FindWhat = .Item(iIndex)
  862. End With
  863. End Property
  864.  
  865. Property Let FindWhat(Optional iIndex As Long = 1, sWhatA As String)
  866. With nFindWhat
  867.     ' Don't use optional parameter on Let
  868.     BugAssert iIndex = 1
  869.     Dim v As Variant, i As Long
  870.     For i = 1 To .Count
  871.         ' If item is in list, move to start of list
  872.         If .Item(i) = sWhatA Then
  873.             .Add sWhatA, , 1
  874.             .Remove i + 1
  875.             NotifySearchChange eseFindWhat
  876.             Exit Property
  877.         End If
  878.     Next
  879.     ' If item isn't in list, add it
  880.     If .Count Then
  881.         .Add sWhatA, , 1
  882.     Else
  883.         .Add sWhatA
  884.     End If
  885.     NotifySearchChange eseFindWhat
  886. End With
  887. End Property
  888.  
  889. Property Get FindWhatCount() As Long
  890.     FindWhatCount = nFindWhat.Count
  891. End Property
  892.  
  893. Property Get FindWhatMax() As Long
  894.     FindWhatMax = cFindWhatMax
  895. End Property
  896.  
  897. Property Let FindWhatMax(cFindWhatMaxA As Long)
  898.     cFindWhatMax = cFindWhatMaxA
  899.     Dim v As Variant, i As Integer
  900.     For i = nFindWhat.Count To cFindWhatMax + 1 Step -1
  901.         ' If item is in list beyond maximum, remove it
  902.         nFindWhat.Remove i
  903.     Next
  904.     NotifySearchChange eseFindWhat
  905. End Property
  906.  
  907. Property Get ReplaceWith(Optional iIndex As Long = 1) As String
  908. Attribute ReplaceWith.VB_MemberFlags = "400"
  909. With nReplaceWith
  910.     If .Count = 0 Or iIndex > .Count Then Exit Property
  911.     ReplaceWith = .Item(iIndex)
  912. End With
  913. End Property
  914.  
  915. Property Let ReplaceWith(Optional iIndex As Long = 1, sWithA As String)
  916. With nReplaceWith
  917.     ' Don't use optional parameter on Let
  918.     BugAssert iIndex = 1
  919.     Dim i As Integer ' i = 0
  920.     For i = 1 To .Count
  921.         ' If item is in list, move to start of list
  922.         If .Item(i) = sWithA Then
  923.             .Add sWithA, , 1
  924.             .Remove i + 1
  925.             NotifySearchChange eseReplaceWith
  926.             Exit Property
  927.         End If
  928.     Next
  929.     ' If item isn't in list, add it
  930.     If .Count Then
  931.         .Add sWithA, , 1
  932.     Else
  933.         .Add sWithA
  934.     End If
  935.     NotifySearchChange eseReplaceWith
  936. End With
  937. End Property
  938.  
  939. Property Get ReplaceWithCount() As Long
  940.     ReplaceWithMax = nReplaceWith.Count
  941. End Property
  942.  
  943. Property Get ReplaceWithMax() As Long
  944.     ReplaceWithMax = cReplaceWithMax
  945. End Property
  946.  
  947. Property Let ReplaceWithMax(cReplaceWithMaxA As Long)
  948.     cReplaceWithMax = cReplaceWithMaxA
  949.     Dim i As Integer
  950.     For i = cReplaceWithMax + 1 To nReplaceWith.Count
  951.         ' If item is in list beyond maximum, remove it
  952.         nReplaceWith.Remove i
  953.     Next
  954.     NotifySearchChange eseReplaceWith
  955. End Property
  956.  
  957. Property Get SearchOptionDirection() As Integer
  958. Attribute SearchOptionDirection.VB_MemberFlags = "400"
  959.     SearchOptionDirection = esdDir
  960. End Property
  961.  
  962. Property Let SearchOptionDirection(ByVal esdDirA As Integer)
  963.     If esdDirA < 0 Or esdDirA > 2 Then esdDirA = 0
  964.     esdDir = esdDirA
  965.     NotifySearchChange eseDirection
  966. End Property
  967.  
  968. Property Get SearchOptionCase() As Boolean
  969.     SearchOptionCase = fSearchOptionCase
  970. End Property
  971.  
  972. Property Let SearchOptionCase(ByVal fSearchOptionCaseA As Boolean)
  973.     fSearchOptionCase = fSearchOptionCaseA
  974.     NotifySearchChange eseCase
  975. End Property
  976.  
  977. ' Left as an exercise
  978. Property Get SearchOptionWord() As Boolean
  979.     SearchOptionWord = fSearchOptionWord
  980. End Property
  981.  
  982. Property Let SearchOptionWord(ByVal fSearchOptionWordA As Boolean)
  983.     fSearchOptionWord = fSearchOptionWordA
  984.     NotifySearchChange eseWholeWord
  985. End Property
  986.  
  987. Property Get SearchActive() As Boolean
  988.     SearchActive = cSearchActive
  989. End Property
  990.  
  991. ' Friend so that only the search form can set this property
  992. Friend Property Let SearchActive(ByVal fSearchActiveA As Boolean)
  993.     ' Use reference count because you could have multiple search forms
  994.     If fSearchActiveA Then
  995.         cSearchActive = cSearchActive + 1
  996.     Else
  997.         cSearchActive = cSearchActive - 1
  998.     End If
  999. End Property
  1000.  
  1001. Property Get SaveWordWrap() As Boolean
  1002.     SaveWordWrap = fSaveWordWrap
  1003. End Property
  1004.  
  1005. Property Let SaveWordWrap(ByVal fSaveWordWrapA As Boolean)
  1006.     SendMessage txt.hWnd, EM_FMTLINES, ByVal -fSaveWordWrapA, ByVal 0&
  1007.     fSaveWordWrap = fSaveWordWrapA
  1008.     
  1009.     PropertyChanged "SaveWordWrap"
  1010. End Property
  1011.  
  1012. ' RichTextBox properties passed through
  1013.  
  1014. Property Get Appearance() As AppearanceConstants
  1015. Attribute Appearance.VB_Description = "Returns/sets the paint style of a control at run time. "
  1016. Attribute Appearance.VB_MemberFlags = "400"
  1017.     Appearance = ordAppearance
  1018. End Property
  1019.  
  1020. Property Let Appearance(ByVal ordAppearanceA As AppearanceConstants)
  1021.     If Ambient.UserMode Then ErrRaise eeSetNotSupportedAtRuntime
  1022.     ChangeStyleBit txt.hWnd, ordAppearanceA = rtfThreeD, ES_SUNKEN
  1023.     ordAppearance = ordAppearanceA
  1024.     PropertyChanged "Appearance"
  1025. End Property
  1026.  
  1027. Property Get AutoVerbMenu() As Boolean
  1028. Attribute AutoVerbMenu.VB_Description = "Returns/sets a value that indicating whether the selected object's verbs will be displayed in a popup menu when the right mouse button is clicked."
  1029.     AutoVerbMenu = txt.AutoVerbMenu
  1030. End Property
  1031.  
  1032. Property Let AutoVerbMenu(ByVal fAutoVerbMenuA As Boolean)
  1033.     txt.AutoVerbMenu = fAutoVerbMenuA
  1034.     PropertyChanged "AutoVerbMenu"
  1035. End Property
  1036.  
  1037. Property Get BackColor() As OLE_COLOR
  1038. Attribute BackColor.VB_Description = "Returns/sets the background color of an object."
  1039.     BackColor = txt.BackColor
  1040. End Property
  1041.  
  1042. Property Let BackColor(ByVal clrBackColor As OLE_COLOR)
  1043.     txt.BackColor = clrBackColor
  1044.     PropertyChanged "BackColor"
  1045. End Property
  1046.  
  1047. Property Get BorderStyle() As RichTextLib.BorderStyleConstants
  1048. Attribute BorderStyle.VB_Description = "Returns/sets the border style for an object."
  1049.     BorderStyle = txt.BorderStyle
  1050. End Property
  1051.  
  1052. Property Let BorderStyle(ByVal ordBorderStyle As RichTextLib.BorderStyleConstants)
  1053.     txt.BorderStyle = ordBorderStyle
  1054.     PropertyChanged "BorderStyle"
  1055. End Property
  1056.  
  1057. Property Get BulletIndent() As Single
  1058. Attribute BulletIndent.VB_Description = "Returns or sets the amount of indent used when SelBullet is set to True."
  1059.     BulletIndent = txt.BulletIndent
  1060. End Property
  1061.  
  1062. Property Let BulletIndent(ByVal rBulletIndentA As Single)
  1063.     If TextMode Then Exit Property
  1064.     txt.BulletIndent = rBulletIndentA
  1065. End Property
  1066.  
  1067. Property Get DirtyBit() As Boolean
  1068. Attribute DirtyBit.VB_MemberFlags = "400"
  1069.     DirtyBit = SendMessage(txt.hWnd, EM_GETMODIFY, ByVal 0&, ByVal 0&)
  1070. End Property
  1071.  
  1072. Property Let DirtyBit(ByVal fDirtyBitA As Boolean)
  1073.     Call SendMessage(txt.hWnd, EM_SETMODIFY, _
  1074.                      ByVal -CLng(fDirtyBitA), ByVal 0&)
  1075.     StatusEvent
  1076. End Property
  1077.  
  1078. #If 0 Then
  1079. Property Get DragIcon() As Picture
  1080.     Set DragIcon = txt.DragIcon
  1081. End Property
  1082.  
  1083. Property Let DragIcon(picDragIconA As Picture)
  1084.     Set txt.DragIcon = picDragIconA
  1085.     PropertyChanged "DragIcon"
  1086. End Property
  1087.  
  1088. Property Get DragMode() As DragModeConstants
  1089.     DragMode = txt.DragMode
  1090. End Property
  1091.  
  1092. Property Let DragMode(ByVal ordDragModeA As DragModeConstants)
  1093.     txt.DragMode = ordDragModeA
  1094.     PropertyChanged "DragMode"
  1095. End Property
  1096. #End If
  1097.  
  1098. ' Read-only, run-time only
  1099. Property Get FilePath() As String
  1100.     FileName = sFilePath
  1101. End Property
  1102.  
  1103. ' Run time or design time
  1104. Property Get FileName() As String
  1105.     If sFilePath <> sEmpty Then FileName = GetFileBaseExt(sFilePath)
  1106. End Property
  1107.  
  1108. ' Design-time only (use LoadFile at run time)
  1109. Property Let FileName(sFileNameA As String)
  1110.     If Ambient.UserMode Then ErrRaise eeSetNotSupportedAtRuntime
  1111.     ' Can't pass through design-time errors
  1112.     On Error GoTo FailFileName
  1113.     If sFileNameA = sEmpty Then
  1114.         ' Empty text only if it comes from a file
  1115.         If sFilePath <> sEmpty Then Text = sEmpty
  1116.         sFilePath = sEmpty
  1117.     Else
  1118.         sFileNameA = GetFullPath(sFileNameA)
  1119.         LoadFile sFileNameA
  1120.         sFilePath = sFileNameA
  1121.     End If
  1122.     PropertyChanged "FileName"
  1123.     Exit Property
  1124. FailFileName:
  1125.     ' Could empty FileName and Text, but I choose to ignore them
  1126. End Property
  1127.  
  1128. Property Get Font() As Font
  1129. Attribute Font.VB_Description = "Returns a Font object."
  1130. Attribute Font.VB_UserMemId = -512
  1131.     Set Font = txt.Font
  1132. End Property
  1133.  
  1134. Property Set Font(ByVal fntA As Font)
  1135.     Dim fDirty As Boolean
  1136.     fDirty = DirtyBit
  1137.     Set txt.Font = fntA
  1138.     ' Changing the font shouldn't dirty the file in TextMode
  1139.     If TextMode Then DirtyBit = fDirty
  1140.     PropertyChanged "Font"
  1141. End Property
  1142.  
  1143. Property Get TextColor() As OLE_COLOR
  1144. Attribute TextColor.VB_Description = "Returns/sets the foreground color used to display text."
  1145. Attribute TextColor.VB_MemberFlags = "400"
  1146.     TextColor = txt.SelColor
  1147. End Property
  1148.  
  1149. Property Let TextColor(ByVal clrTextColorA As OLE_COLOR)
  1150. With txt
  1151.     If TextMode Then
  1152.         Dim fEnabled As Boolean, fDirty As Boolean
  1153.         Dim iStart As Long, iLength As Long
  1154.         fDirty = DirtyBit
  1155.         ' Save selection
  1156.         SelVisible False
  1157.         iStart = .SelStart
  1158.         iLength = .SelLength
  1159.         ' Select all and change color
  1160.         .SelStart = 0
  1161.         .SelLength = Characters
  1162.         .SelColor = clrTextColorA
  1163.         ' Restore selection
  1164.         .SelStart = iStart
  1165.         .SelLength = iLength
  1166.         SelVisible True
  1167.         ' Changing the color shouldn't dirty the text in text mode
  1168.         DirtyBit = fDirty
  1169.     End If
  1170.     PropertyChanged "TextColor"
  1171. End With
  1172. End Property
  1173.  
  1174. Property Get HideSelection() As Boolean
  1175. Attribute HideSelection.VB_Description = "Returns/sets a value that specifies if the selected item remains highlighted when a control loses focus."
  1176.     HideSelection = txt.HideSelection
  1177. End Property
  1178.  
  1179. Property Let HideSelection(ByVal fHideSelectionA As Boolean)
  1180.     txt.HideSelection = fHideSelectionA
  1181. End Property
  1182.  
  1183. ' Read only
  1184. Property Get hWnd() As Long
  1185. Attribute hWnd.VB_Description = "Returns a handle to a control."
  1186. Attribute hWnd.VB_MemberFlags = "400"
  1187.     hWnd = txt.hWnd
  1188. End Property
  1189.  
  1190. Property Get Locked() As Boolean
  1191. Attribute Locked.VB_Description = "Returns/sets a value indicating whether the contents can be edited."
  1192.     Locked = txt.Locked
  1193. End Property
  1194.  
  1195. Property Let Locked(ByVal fLockedA As Boolean)
  1196.     txt.Locked = fLockedA
  1197.     PropertyChanged "Locked"
  1198. End Property
  1199.  
  1200. Property Get MousePointer() As MousePointerConstants
  1201. Attribute MousePointer.VB_Description = "Returns/sets a value indicating the type of mouse pointer displayed when the mouse is over the control at run time."
  1202.     MousePointer = txt.MousePointer
  1203. End Property
  1204.  
  1205. Property Let MousePointer(ByVal ordMousePointerA As MousePointerConstants)
  1206.     txt.MousePointer = ordMousePointerA
  1207.     PropertyChanged "MousePointer"
  1208. End Property
  1209.  
  1210. Property Get MouseIcon() As Picture
  1211. Attribute MouseIcon.VB_Description = "Sets a custom mouse icon."
  1212.     Set MouseIcon = txt.MouseIcon
  1213. End Property
  1214.  
  1215. Property Set MouseIcon(ByVal picMouseIcon As Picture)
  1216.     Set txt.MouseIcon = picMouseIcon
  1217.     PropertyChanged "MouseIcon"
  1218. End Property
  1219.  
  1220. Property Get OLEDragMode() As OLEDragConstants
  1221. Attribute OLEDragMode.VB_Description = "Returns/Sets whether this control can act as an OLE drag/drop source, and whether this process is started automatically or under programmatic control."
  1222.     OLEDragMode = txt.OLEDragMode
  1223. End Property
  1224.  
  1225. Property Let OLEDragMode(ByVal ordOLEDragMode As OLEDragConstants)
  1226.     txt.OLEDragMode() = ordOLEDragMode
  1227.     PropertyChanged "OLEDragMode"
  1228. End Property
  1229.  
  1230. Property Get OLEDropMode() As OLEDropConstants
  1231. Attribute OLEDropMode.VB_Description = "Returns/Sets whether this control can act as an OLE drop target."
  1232.     OLEDropMode = txt.OLEDropMode
  1233. End Property
  1234.  
  1235. Property Let OLEDropMode(ByVal ordOLEDropMode As OLEDropConstants)
  1236.     txt.OLEDropMode() = ordOLEDropMode
  1237.     PropertyChanged "OLEDropMode"
  1238. End Property
  1239.  
  1240. Property Get OLEObjects() As IOLEObjects
  1241. Attribute OLEObjects.VB_Description = "The insertable objects in an RTF file."
  1242.     Set OLEObjects = txt.OLEObjects
  1243. End Property
  1244.  
  1245. Property Get OverWrite() As Boolean
  1246.     OverWrite = fOverWrite
  1247. End Property
  1248.  
  1249. Property Let OverWrite(ByVal fOverWriteA As Boolean)
  1250.     ' Only change if value changed
  1251.     If fOverWriteA <> fOverWrite Then
  1252.         fOverWrite = fOverWriteA
  1253.         ' Change the keystate to match
  1254.         SendMessage txt.hWnd, WM_KEYDOWN, ByVal VK_INSERT, ByVal &H510001
  1255.         SendMessage txt.hWnd, WM_KEYUP, ByVal VK_INSERT, ByVal &HC0510001
  1256.         StatusEvent
  1257.         PropertyChanged "OverWrite"
  1258.     End If
  1259. End Property
  1260.  
  1261. Property Get ScrollBars() As ScrollBarsConstants
  1262. Attribute ScrollBars.VB_Description = "Returns/sets a value indicating whether the control has horizontal or vertical scroll bars."
  1263.     ScrollBars = ordScrollBars
  1264. End Property
  1265.  
  1266. Property Let ScrollBars(ordScrollBarsA As ScrollBarsConstants)
  1267.     Dim af As Long, hParent As Long
  1268.     Const afMask As Long = Not (WS_HSCROLL Or WS_VSCROLL)
  1269.     af = GetWindowLong(txt.hWnd, GWL_STYLE) And afMask
  1270.     
  1271.     ' Call InitScrollBars once for the lifetime of control
  1272.     Static fNotFirstTime As Boolean
  1273.     If fNotFirstTime = False Then
  1274.         InitScrollBars af
  1275.         fNotFirstTime = True
  1276.     End If
  1277.     
  1278.     Select Case ordScrollBarsA
  1279.     Case rtfNone
  1280.         ' Done
  1281.     Case rtfHorizontal
  1282.         af = af Or WS_HSCROLL
  1283.     Case rtfVertical
  1284.         af = af Or WS_VSCROLL
  1285.     Case rtfBoth
  1286.         af = af Or WS_HSCROLL Or WS_VSCROLL
  1287.     End Select
  1288.     Call SetWindowLong(hWnd, GWL_STYLE, af)
  1289.     ' Reset the parent so that change will "take"
  1290.     hParent = GetParent(hWnd)
  1291.     SetParent hWnd, hParent
  1292.     ' Redraw for added insurance
  1293.     Call SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, _
  1294.                       SWP_NOZORDER Or SWP_NOSIZE Or _
  1295.                       SWP_NOMOVE Or SWP_DRAWFRAME)
  1296.  
  1297.     ordScrollBars = ordScrollBarsA
  1298.     PropertyChanged "ScrollBars"
  1299. End Property
  1300.  
  1301. Property Get RightMargin() As Single
  1302. Attribute RightMargin.VB_Description = "Sets the right margin used for textwrap, centering, etc."
  1303.     RightMargin = txt.RightMargin
  1304. End Property
  1305.  
  1306. Property Let RightMargin(ByVal rRightMargin As Single)
  1307.     If rRightMargin < 0 Or rRightMargin > 65535 Then
  1308.         rRightMargin = 65535
  1309.     End If
  1310.     txt.RightMargin = rRightMargin
  1311.     PropertyChanged "RightMargin"
  1312. End Property
  1313.  
  1314. Property Get SelAlignment() As Variant
  1315. Attribute SelAlignment.VB_Description = "Returns/sets a value that controls the alignment of the paragraphs."
  1316. Attribute SelAlignment.VB_MemberFlags = "400"
  1317.     If TextMode Then
  1318.         SelAlignment = Null
  1319.     Else
  1320.         SelAlignment = txt.SelAlignment
  1321.     End If
  1322. End Property
  1323.  
  1324. Property Let SelAlignment(ByVal vSelAlignmentA As Variant)
  1325.     If TextMode Then Exit Property
  1326.     txt.SelAlignment = vSelAlignmentA
  1327. End Property
  1328.  
  1329. Property Get SelBold() As Variant
  1330. Attribute SelBold.VB_Description = "Returns/set the bold format of the currently selected text."
  1331. Attribute SelBold.VB_MemberFlags = "400"
  1332.     If TextMode Then
  1333.         SelBold = Null
  1334.     Else
  1335.         SelBold = txt.SelBold
  1336.     End If
  1337. End Property
  1338.  
  1339. Property Let SelBold(ByVal vSelBold As Variant)
  1340.     If TextMode Then Exit Property
  1341.     txt.SelBold = vSelBold
  1342. End Property
  1343.  
  1344. Property Get SelBullet() As Variant
  1345. Attribute SelBullet.VB_Description = "Returns/sets a value that determines if a paragraph in the control containing the current selection or insertion point has the bullet style."
  1346. Attribute SelBullet.VB_MemberFlags = "400"
  1347.     If TextMode Then
  1348.         SelBullet = Null
  1349.     Else
  1350.         SelBullet = txt.SelBullet
  1351.     End If
  1352. End Property
  1353.  
  1354. Property Let SelBullet(ByVal vSelBullet As Variant)
  1355.     If TextMode Then Exit Property
  1356.     txt.SelBullet = vSelBullet
  1357. End Property
  1358.  
  1359. Property Get SelCharOffset() As Variant
  1360. Attribute SelCharOffset.VB_Description = "Returns/sets a value that determines whether text in the control appears on the baseline (normal), as a superscript above the baseline, or as a subscript below the baseline."
  1361. Attribute SelCharOffset.VB_MemberFlags = "400"
  1362.     If TextMode Then
  1363.         SelCharOffset = Null
  1364.     Else
  1365.         SelCharOffset = txt.SelCharOffset
  1366.     End If
  1367. End Property
  1368.  
  1369. Property Let SelCharOffset(ByVal vSelCharOffset As Variant)
  1370.     If TextMode Then Exit Property
  1371.     txt.SelCharOffset = vSelCharOffset
  1372. End Property
  1373.  
  1374. Property Get SelColor() As Variant
  1375. Attribute SelColor.VB_Description = "Returns/sets a value that determines the color of text in the control."
  1376. Attribute SelColor.VB_MemberFlags = "400"
  1377.     If TextMode Then
  1378.         SelColor = Null
  1379.     Else
  1380.         SelColor = txt.SelColor
  1381.     End If
  1382. End Property
  1383.  
  1384. Property Let SelColor(ByVal vSelColor As Variant)
  1385.     If TextMode Then Exit Property
  1386.     txt.SelColor = vSelColor
  1387. End Property
  1388.  
  1389. Property Get SelFontName() As Variant
  1390. Attribute SelFontName.VB_Description = "Returns/sets the font used to display the currently selected text or the character(s) immediately following the insertion point in the control."
  1391. Attribute SelFontName.VB_MemberFlags = "400"
  1392.     If TextMode Then
  1393.         SelFontName = Null
  1394.     Else
  1395.         SelFontName = txt.SelFontName
  1396.     End If
  1397. End Property
  1398.  
  1399. Property Let SelFontName(ByVal vSelFontName As Variant)
  1400.     If TextMode Then Exit Property
  1401.     txt.SelFontName = vSelFontName
  1402. End Property
  1403.  
  1404. Property Get SelFontSize() As Variant
  1405. Attribute SelFontSize.VB_Description = "Returns/sets a value that specifies the size of the font used to display text."
  1406. Attribute SelFontSize.VB_MemberFlags = "400"
  1407.     If TextMode Then
  1408.         SelFontSize = Null
  1409.     Else
  1410.         SelFontSize = txt.SelFontSize
  1411.     End If
  1412. End Property
  1413.  
  1414. Property Let SelFontSize(ByVal vSelFontSize As Variant)
  1415.     If TextMode Then Exit Property
  1416.     txt.SelFontSize = vSelFontSize
  1417. End Property
  1418.  
  1419. Property Get SelHangingIndent() As Variant
  1420. Attribute SelHangingIndent.VB_Description = "Returns/sets the distance between left edge of the first line of text in the selected paragraph(s) (as specified by SelIndent) and the left edge of subsequent lines of text in the same paragraphs."
  1421. Attribute SelHangingIndent.VB_MemberFlags = "400"
  1422.     If TextMode Then
  1423.         SelHangingIndent = Null
  1424.     Else
  1425.         SelHangingIndent = txt.SelHangingIndent
  1426.     End If
  1427. End Property
  1428.  
  1429. Property Let SelHangingIndent(ByVal vSelHangingIndent As Variant)
  1430.     If TextMode Then Exit Property
  1431.     txt.SelHangingIndent = vSelHangingIndent
  1432. End Property
  1433.  
  1434. Property Get SelIndent() As Variant
  1435. Attribute SelIndent.VB_Description = "Returns/sets the distance between the left edge of the control and the left edge of the text that is selected or added at the current insertion point."
  1436. Attribute SelIndent.VB_MemberFlags = "400"
  1437.     If TextMode Then
  1438.         SelIndent = Null
  1439.     Else
  1440.         SelIndent = txt.SelIndent
  1441.     End If
  1442. End Property
  1443.  
  1444. Property Let SelIndent(ByVal vSelIndent As Variant)
  1445.     If TextMode Then Exit Property
  1446.     txt.SelIndent = vSelIndent
  1447. End Property
  1448.  
  1449. Property Get SelItalic() As Variant
  1450. Attribute SelItalic.VB_Description = "Returns/set the italic format of the currently selected text."
  1451. Attribute SelItalic.VB_MemberFlags = "400"
  1452.     If TextMode Then
  1453.         SelItalic = Null
  1454.     Else
  1455.         SelItalic = txt.SelItalic
  1456.     End If
  1457. End Property
  1458.  
  1459. Property Let SelItalic(ByVal vSelItalic As Variant)
  1460.     If TextMode Then Exit Property
  1461.     txt.SelItalic = vSelItalic
  1462. End Property
  1463.  
  1464. Property Get SelLength() As Long
  1465. Attribute SelLength.VB_Description = "Returns/sets the number of characters selected."
  1466. Attribute SelLength.VB_MemberFlags = "400"
  1467.     SelLength = txt.SelLength
  1468. End Property
  1469.  
  1470. Property Let SelLength(ByVal iSelLengthA As Long)
  1471.     txt.SelLength = iSelLengthA
  1472. End Property
  1473.  
  1474. Property Get SelProtected() As Variant
  1475. Attribute SelProtected.VB_Description = "Returns/sets a value that determines if the selected text is protected against editing."
  1476. Attribute SelProtected.VB_MemberFlags = "400"
  1477.     If TextMode Then
  1478.         SelProtected = Null
  1479.     Else
  1480.         SelProtected = txt.SelProtected
  1481.     End If
  1482. End Property
  1483.  
  1484. Property Let SelProtected(ByVal vSelProtected As Variant)
  1485.     If TextMode Then Exit Property
  1486.     txt.SelProtected = vSelProtected
  1487. End Property
  1488.  
  1489. Property Get SelRightIndent() As Variant
  1490. Attribute SelRightIndent.VB_Description = "Returns/sets the distance between the right edge of the control and the right edge of the text that is selected or added at the current insertion point."
  1491. Attribute SelRightIndent.VB_MemberFlags = "400"
  1492.     If TextMode Then
  1493.         SelRightIndent = Null
  1494.     Else
  1495.         SelRightIndent = txt.SelRightIndent
  1496.     End If
  1497. End Property
  1498.  
  1499. Property Let SelRightIndent(ByVal vSelRightIndent As Variant)
  1500.     If TextMode Then Exit Property
  1501.     txt.SelRightIndent = vSelRightIndent
  1502. End Property
  1503.  
  1504. Property Get SelRTF() As String
  1505. Attribute SelRTF.VB_Description = "Returns/sets the text (in .RTF format) in the current selection of a control."
  1506. Attribute SelRTF.VB_MemberFlags = "400"
  1507.     If TextMode Then Exit Property
  1508.     SelRTF = txt.SelRTF
  1509. End Property
  1510.  
  1511. Property Let SelRTF(sSelRTFA As String)
  1512.     If TextMode Then Exit Property
  1513.     txt.SelRTF = sSelRTFA
  1514. End Property
  1515.  
  1516. Property Get SelStart() As Long
  1517. Attribute SelStart.VB_Description = "Returns/sets the starting point of text selected; indicates the position of the insertion point if no text is selected."
  1518. Attribute SelStart.VB_MemberFlags = "400"
  1519.     SelStart = txt.SelStart
  1520. End Property
  1521.  
  1522. Property Let SelStart(ByVal iSelStartA As Long)
  1523.     txt.SelStart = iSelStartA
  1524. End Property
  1525.  
  1526. Property Get SelStrikeThru() As Variant
  1527. Attribute SelStrikeThru.VB_Description = "Returns/set the strikethru format of the currently selected text."
  1528. Attribute SelStrikeThru.VB_MemberFlags = "400"
  1529.     If TextMode Then
  1530.         SelStrikeThru = Null
  1531.     Else
  1532.         SelStrikeThru = txt.SelStrikeThru
  1533.     End If
  1534. End Property
  1535.  
  1536. Property Let SelStrikeThru(ByVal vSelStrikeThru As Variant)
  1537.     If TextMode Then Exit Property
  1538.     txt.SelStrikeThru = vSelStrikeThru
  1539. End Property
  1540.  
  1541. Property Get SelTabCount() As Variant
  1542. Attribute SelTabCount.VB_Description = "Returns/sets the number of tabs.  Used in conjunction with the SelTab Property."
  1543. Attribute SelTabCount.VB_MemberFlags = "400"
  1544.     If TextMode Then
  1545.         SelTabCount = Null
  1546.     Else
  1547.         SelTabCount = txt.SelTabCount
  1548.     End If
  1549. End Property
  1550.  
  1551. Property Let SelTabCount(ByVal vSelTabCount As Variant)
  1552.     If TextMode Then Exit Property
  1553.     txt.SelTabCount = vSelTabCount
  1554. End Property
  1555.  
  1556. Property Get SelTabs(iElement As Integer) As Variant
  1557. Attribute SelTabs.VB_Description = "Returns/sets the absolute tab positions of text.  Used in conjunction with the SelTabCount Property."
  1558. Attribute SelTabs.VB_MemberFlags = "400"
  1559.     If TextMode Then
  1560.         SelTabs = Null
  1561.     Else
  1562.         SelTabs = txt.SelTabs(iElement)
  1563.     End If
  1564. End Property
  1565.  
  1566. Property Let SelTabs(iElement As Integer, ByVal vSelTabs As Variant)
  1567.     If TextMode Then Exit Property
  1568.     txt.SelTabs(iElement) = vSelTabs
  1569. End Property
  1570.  
  1571. Property Get SelText() As String
  1572. Attribute SelText.VB_Description = "Returns/sets the string containing the currently selected text; consists of a zero-length string if no characters are selected."
  1573. Attribute SelText.VB_MemberFlags = "400"
  1574.     SelText = txt.SelText
  1575. End Property
  1576.  
  1577. Property Let SelText(sSelTextA As String)
  1578.     txt.SelText = sSelTextA
  1579. End Property
  1580.  
  1581. Property Get SelUnderline() As Variant
  1582. Attribute SelUnderline.VB_Description = "Returns/set the underline format of the currently selected text."
  1583. Attribute SelUnderline.VB_MemberFlags = "400"
  1584.     If TextMode Then
  1585.         SelUnderline = Null
  1586.     Else
  1587.         SelUnderline = txt.SelUnderline
  1588.     End If
  1589. End Property
  1590.  
  1591. Property Let SelUnderline(ByVal vSelUnderline As Variant)
  1592.     If TextMode Then Exit Property
  1593.     txt.SelUnderline = vSelUnderline
  1594. End Property
  1595.  
  1596. Property Get Text() As String
  1597. Attribute Text.VB_Description = "Returns/sets the text contained in an object."
  1598. Attribute Text.VB_UserMemId = 0
  1599.     If Ambient.UserMode Then
  1600.         Text = txt.Text
  1601.     Else
  1602.         ' Show only the first line in property page
  1603.         Dim iPos As Long
  1604.         iPos = InStr(txt.Text, sCr)
  1605.         If iPos Then
  1606.             Text = Left$(txt.Text, iPos - 1) & "..."
  1607.         Else
  1608.             Text = txt.Text
  1609.         End If
  1610.     End If
  1611. End Property
  1612.  
  1613. Property Let Text(sTextA As String)
  1614.     txt.Text = sTextA
  1615.     PropertyChanged "Text"
  1616. End Property
  1617.  
  1618. Property Get TextRTF() As String
  1619. Attribute TextRTF.VB_Description = "Returns/sets the text of the control, including all .RTF code."
  1620. Attribute TextRTF.VB_MemberFlags = "400"
  1621.     If TextMode Then
  1622.         TextRTF = txt.TextRTF
  1623.     Else
  1624.         TextRTF = sEmpty
  1625.     End If
  1626. End Property
  1627.  
  1628. Property Let TextRTF(sTextRTFA As String)
  1629.     If fTextMode = rtfRTF Then
  1630.         TextRTF = txt.TextRTF
  1631.     ' Else ignore
  1632.     End If
  1633. End Property
  1634.  
  1635. Property Get ScaleLeft() As Single
  1636.     Dim rc As RECT
  1637.     SendMessage txt.hWnd, EM_GETRECT, ByVal 0&, rc
  1638.     ScaleLeft = Extender.Left + (rc.Left * Screen.TwipsPerPixelY)
  1639. End Property
  1640.  
  1641. Property Get ScaleTop() As Single
  1642.     Dim rc As RECT
  1643.     SendMessage txt.hWnd, EM_GETRECT, ByVal 0&, rc
  1644.     ScaleTop = Extender.Top + (rc.Top * Screen.TwipsPerPixelY)
  1645. End Property
  1646.  
  1647. Property Get ScaleWidth() As Single
  1648.     Dim rc As RECT
  1649.     SendMessage txt.hWnd, EM_GETRECT, ByVal 0&, rc
  1650.     ScaleWidth = (rc.Right - rc.Left) * Screen.TwipsPerPixelX
  1651. End Property
  1652.  
  1653. Property Get ScaleHeight() As Single
  1654.     Dim rc As RECT
  1655.     SendMessage txt.hWnd, EM_GETRECT, ByVal 0&, rc
  1656.     ScaleHeight = (rc.bottom - rc.Top) * Screen.TwipsPerPixelY
  1657. End Property
  1658.  
  1659. Property Get LeftMargin() As Single
  1660.     Dim dx As Long
  1661.     dx = SendMessage(txt.hWnd, EM_GETMARGINS, ByVal 0&, ByVal 0&)
  1662.     LeftMargin = LoWord(dx)
  1663. End Property
  1664.  
  1665. Property Let LeftMargin(ByVal rLeftMargin As Single)
  1666.     Dim dx As Long
  1667.     Const EC_LEFTMARGIN = 1
  1668.     dx = CLng(rLeftMargin)
  1669.     SendMessage txt.hWnd, EM_SETMARGINS, ByVal EC_LEFTMARGIN, ByVal dx
  1670. End Property
  1671.  
  1672. '' Methods passed through
  1673.  
  1674. Public Sub Drag(Optional ByVal ordAction As Integer = vbBeginDrag)
  1675.     txt.Drag ordAction
  1676. End Sub
  1677.  
  1678. ' Pass through txt method, but it's similar to FindNext
  1679. Function Find(sSearch As String, Optional vStart As Variant, _
  1680.               Optional vEnd As Variant, _
  1681.               Optional afOptions As Integer = 0) As Long
  1682. Attribute Find.VB_Description = "Searches the text for a given string."
  1683. With txt
  1684.     If IsMissing(vStart) Then
  1685.         If IsMissing(vEnd) Then
  1686.             ' Both missing
  1687.             If txt.SelLength > 0 Then
  1688.                 vStart = .SelStart
  1689.                 vEnd = .SelStart + .SelLength
  1690.             Else
  1691.                 ' Enhance to start at current position
  1692.                 vStart = .SelStart
  1693.                 vEnd = .SelStart - 1
  1694.             End If
  1695.         Else
  1696.             ' Start missing
  1697.             vStart = .SelStart
  1698.         End If
  1699.     Else
  1700.         If IsMissing(vEnd) Then
  1701.             ' End missing
  1702.             vEnd = Characters
  1703.         ' else
  1704.             ' None missing
  1705.         End If
  1706.     End If
  1707.     .Find sSearch, vStart, vEnd, afOptions
  1708. End With
  1709. End Function
  1710.  
  1711. ' Run-time only (use FileName at design time)
  1712. Sub LoadFile(sFileNameA As String, _
  1713.              Optional ordTextModeA As ELoadSave = elsDefault)
  1714. Attribute LoadFile.VB_Description = "Loads an .RTF file or text file."
  1715.     If sFileNameA = sEmpty Then Exit Sub
  1716.     BugAssert ordTextModeA >= elsDefault And ordTextModeA <= elstext
  1717.     If ordTextModeA = elsDefault Then
  1718.         ordTextModeA = IIf(TextMode, elstext, elsrtf)
  1719.     End If
  1720.     If TextMode Then Set Font = fontDefault
  1721.     ' Don't reload clean file
  1722.     sFileNameA = GetFullPath(sFileNameA)
  1723.     If sFileNameA = sFilePath And DirtyBit = False Then Exit Sub
  1724.     ' Use RichTextBox method (raise unhandled errors to caller)
  1725.     txt.LoadFile sFileNameA, ordTextModeA
  1726.     sFilePath = sFileNameA
  1727.     DirtyBit = False
  1728. End Sub
  1729.  
  1730. Sub Move(X As Single, Optional Y As Variant, _
  1731.          Optional dx As Variant, Optional dy As Variant)
  1732.     If IsMissing(Y) Then
  1733.         txt.Move X
  1734.     ElseIf IsMissing(dx) Then
  1735.         txt.Move X, Y
  1736.     ElseIf IsMissing(dy) Then
  1737.         txt.Move X, Y, dx
  1738.     Else
  1739.         txt.Move X, Y, dx, dy
  1740.     End If
  1741. End Sub
  1742.  
  1743. Public Sub OLEDrag()
  1744. Attribute OLEDrag.VB_Description = "Starts an OLE drag/drop event with the given control as the source."
  1745.     txt.OLEDrag
  1746. End Sub
  1747.  
  1748. Public Sub SelPrint(ByVal hDC As Long, Optional fPrintAll As Boolean)
  1749. Attribute SelPrint.VB_Description = "Sends formatted text to a device for printing."
  1750. With txt
  1751.     If fPrintAll Then
  1752.         Dim c As Long
  1753.         c = .SelLength
  1754.         .SelLength = 0
  1755.         .SelPrint hDC
  1756.         .SelLength = c
  1757.     Else
  1758.         .SelPrint hDC
  1759.     End If
  1760. End With
  1761. End Sub
  1762.  
  1763. Public Sub Refresh()
  1764. Attribute Refresh.VB_Description = "Forces a complete repaint."
  1765.     txt.Refresh
  1766. End Sub
  1767.  
  1768. Public Sub SetFocus()
  1769.     txt.SetFocus
  1770. End Sub
  1771.  
  1772. Sub SaveFile(sFileNameA As String, _
  1773.              Optional ordTextModeA As ELoadSave = elsDefault)
  1774.     If sFileNameA = sEmpty Then Exit Sub
  1775.     BugAssert ordTextModeA >= elsDefault And ordTextModeA <= elstext
  1776.     If ordTextModeA = elsDefault Then
  1777.         ordTextModeA = IIf(TextMode, elstext, elsrtf)
  1778.     End If
  1779.     ' Use RichTextBox method (raise unhandled errors to caller)
  1780.     sFileNameA = GetFullPath(sFileNameA)
  1781.     txt.SaveFile sFileNameA, ordTextModeA
  1782.     sFilePath = sFileNameA
  1783.     DirtyBit = False
  1784. End Sub
  1785.  
  1786. Sub ShowWhatsThis()
  1787.     txt.ShowWhatsThis
  1788. End Sub
  1789.  
  1790. Public Sub Span(sCharSet As String, _
  1791.                 Optional fForward As Boolean = True, _
  1792.                 Optional fNegate As Boolean = False)
  1793.     txt.Span sCharSet, fForward, fNegate
  1794. End Sub
  1795.  
  1796. Public Sub UpTo(sCharSet As String, _
  1797.                 Optional fForward As Boolean = True, _
  1798.                 Optional fNegate As Boolean = False)
  1799. Attribute UpTo.VB_Description = "Moves the insertion point up to, but not including, the first character that is a member of the specified character set."
  1800.     txt.UpTo sCharSet, fForward, fNegate
  1801. End Sub
  1802.  
  1803. ' Events
  1804. Sub txt_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
  1805.     RaiseEvent MouseUp(Button, Shift, X, Y)
  1806. End Sub
  1807.  
  1808. Sub txt_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  1809.     RaiseEvent MouseMove(Button, Shift, X, Y)
  1810. End Sub
  1811.  
  1812. Sub txt_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  1813.     RaiseEvent MouseDown(Button, Shift, X, Y)
  1814. End Sub
  1815.  
  1816. Sub txt_KeyUp(KeyCode As Integer, Shift As Integer)
  1817.     If KeyCode = vbKeyInsert Then
  1818.         ' Insert state changed, so change the variable to match
  1819.         fOverWrite = Not fOverWrite
  1820.         StatusEvent
  1821.     End If
  1822.     RaiseEvent KeyUp(KeyCode, Shift)
  1823. End Sub
  1824.  
  1825. Sub txt_KeyPress(KeyAscii As Integer)
  1826.     RaiseEvent KeyPress(KeyAscii)
  1827. End Sub
  1828.  
  1829. Sub txt_KeyDown(KeyCode As Integer, Shift As Integer)
  1830.     RaiseEvent KeyDown(KeyCode, Shift)
  1831. End Sub
  1832.  
  1833. Sub txt_DblClick()
  1834.     RaiseEvent DblClick
  1835. End Sub
  1836.  
  1837. Sub txt_Click()
  1838.     RaiseEvent Click
  1839. End Sub
  1840.  
  1841. Sub txt_Change()
  1842.     RaiseEvent Change
  1843. End Sub
  1844.  
  1845. Private Sub txt_OLECompleteDrag(Effect As Long)
  1846.     RaiseEvent OLECompleteDrag(Effect)
  1847. End Sub
  1848.  
  1849. Private Sub txt_OLEDragDrop(Data As RichTextLib.DataObject, Effect As Long, _
  1850.                             Button As Integer, Shift As Integer, _
  1851.                             X As Single, Y As Single)
  1852.     RaiseEvent OLEDragDrop(Data, Effect, Button, Shift, X, Y)
  1853. End Sub
  1854.  
  1855. Private Sub txt_OLEDragOver(Data As RichTextLib.DataObject, Effect As Long, _
  1856.                             Button As Integer, Shift As Integer, _
  1857.                             X As Single, Y As Single, State As Integer)
  1858.     RaiseEvent OLEDragOver(Data, Effect, Button, Shift, X, Y, State)
  1859. End Sub
  1860.  
  1861. Private Sub txt_OLEGiveFeedback(Effect As Long, DefaultCursors As Boolean)
  1862.     RaiseEvent OLEGiveFeedback(Effect, DefaultCursors)
  1863. End Sub
  1864.  
  1865. Private Sub txt_OLESetData(Data As RichTextLib.DataObject, DataFormat As Integer)
  1866.     RaiseEvent OLESetData(Data, DataFormat)
  1867. End Sub
  1868.  
  1869. Private Sub txt_OLEStartDrag(Data As RichTextLib.DataObject, AllowedEffects As Long)
  1870.     RaiseEvent OLEStartDrag(Data, AllowedEffects)
  1871. End Sub
  1872.  
  1873. Private Sub txt_SelChange()
  1874.     RaiseEvent SelChange
  1875.     StatusEvent
  1876. End Sub
  1877.  
  1878. Private Sub StatusEvent()
  1879.     Dim iLine As Long, cLine As Long, iCol As Long, i As Long
  1880.     Dim cCol As Long, iChar As Long, cChar As Long
  1881.         
  1882.     ' Count of lines
  1883.     cLine = SendMessage(txt.hWnd, EM_GETLINECOUNT, ByVal 0&, ByVal 0&)
  1884.     ' Current line (zero adjusted)
  1885.     iLine = 1 + txt.GetLineFromChar(txt.SelStart)
  1886.     ' Current character
  1887.     iChar = txt.SelStart + 1
  1888.     ' Length is position of last line plus length of last line
  1889.     cChar = SendMessage(txt.hWnd, EM_LINEINDEX, ByVal cLine - 1, ByVal 0&)
  1890.     i = SendMessage(txt.hWnd, EM_LINELENGTH, ByVal cChar - 1, ByVal 0&)
  1891.     cChar = cChar + i
  1892.     ' Column count is current line length
  1893.     cCol = SendMessage(txt.hWnd, EM_LINELENGTH, ByVal iChar - 1, ByVal 0&)
  1894.     ' Column is current position minus position of line start
  1895.     i = SendMessage(txt.hWnd, EM_LINEINDEX, ByVal iLine - 1, ByVal 0&)
  1896.     iCol = iChar - i
  1897.     RaiseEvent StatusChange(iLine, cLine, iCol, cCol, iChar, cChar, DirtyBit)
  1898. End Sub
  1899.  
  1900. '' Private helpers
  1901. Private Function FilterString() As String
  1902.     Dim s As String, v As Variant
  1903.     For Each v In nFilters
  1904.         s = s & v & "|"
  1905.     Next
  1906.     FilterString = Left$(s, Len(s) - 1)
  1907. End Function
  1908.  
  1909. Private Sub StringFilter(sFilters As String)
  1910.     '
  1911. End Sub
  1912.  
  1913. Private Sub InitFilters()
  1914. With nFilters
  1915.     If .Count = 0 Then
  1916.         .Add "Text files (*.txt): *.txt"
  1917.         .Add "Rich text files (*.rtf): *.rtf"
  1918.         .Add "All files (*.*): *.*"
  1919.     End If
  1920. End With
  1921. End Sub
  1922.  
  1923. ' For reasons unknown, the rich text box ScrollBars property
  1924. ' misbehaves at design time. InitScrollBars hacks around this
  1925. ' problem by setting horizontal and vertical scroll bars in
  1926. ' succession, after which the ScrollBars property works correctly.
  1927. Private Sub InitScrollBars(af As Long)
  1928.     Dim hParent As Long
  1929.     
  1930.     ' Set horizontal scroll bar
  1931.     Call SetWindowLong(hWnd, GWL_STYLE, af Or WS_HSCROLL)
  1932.     ' Reset the parent so that change will "take"
  1933.     hParent = GetParent(hWnd)
  1934.     SetParent hWnd, hParent
  1935.     ' Redraw for added insurance
  1936.     Call SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, _
  1937.                       SWP_NOZORDER Or SWP_NOSIZE Or _
  1938.                       SWP_NOMOVE Or SWP_DRAWFRAME)
  1939.                       
  1940.     ' Set vertical scroll bar
  1941.     Call SetWindowLong(hWnd, GWL_STYLE, af Or WS_VSCROLL)
  1942.     ' Reset the parent so that change will "take"
  1943.     hParent = GetParent(hWnd)
  1944.     SetParent hWnd, hParent
  1945.     ' Redraw for added insurance
  1946.     Call SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, _
  1947.                       SWP_NOZORDER Or SWP_NOSIZE Or _
  1948.                       SWP_NOMOVE Or SWP_DRAWFRAME)
  1949. End Sub
  1950.  
  1951. Sub NotifySearchChange(ByVal ese As ESearchEvent)
  1952.     RaiseEvent SearchChange(ese)
  1953.     If SearchActive Then finddlg.SearchChange ese
  1954. End Sub
  1955.  
  1956.